/*
 * Rectangle.cpp
 *
 *  Created on: Oct 28, 2012
 *      Author: Bhupendra Aole
 */

#include <iostream>
#include <sstream>
#include <d3dx9math.h>
#include "Rectangle.h"

using namespace std;

namespace aole {

//--------------------------------------------------------------------------------------
// Structures
//--------------------------------------------------------------------------------------
struct SimpleVertex {
	D3DXVECTOR3 Pos;
	D3DXVECTOR4 Col;
};

int Rectangle::setProperty( const char* name, const char* value ) {
	if ( DXObject::setProperty( name, value ) )
		return 1;

	istringstream ss( value );
	if ( !strcmp( name, "x" ) ) {
		ss >> xpos;
		return 1;
	} else if ( !strcmp( name, "y" ) ) {
		ss >> ypos;
		return 1;
	} else if ( !strcmp( name, "w" ) ) {
		ss >> width;
		return 1;
	} else if ( !strcmp( name, "h" ) ) {
		ss >> height;
		return 1;
	}

	cout << "Property not found: " << name << " = " << value << endl;
	return 0;
}

void Rectangle::create( DXEngine* engine ) {
	ID3D11Device* pd3dDevice = engine->getDevice();
	ID3D11DeviceContext* context = engine->getContext();

	// Compile the vertex shader
	ID3DBlob* pVSBlob = NULL;
	HRESULT hr = CompileShaderFromFile( L"Shader.fx", "VS", "vs_4_0",
			&pVSBlob );
	if ( FAILED( hr )) {
		MessageBox( NULL, L"Failed to compile FX file.", L"Error", MB_OK );
		return;
	}

	// Create the vertex shader
	hr = pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(),
			pVSBlob->GetBufferSize(), NULL, &vertexShader );
	if ( FAILED( hr )) {
		pVSBlob->Release();
		return;
	}

	// Define the input layout
	D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0,
			DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12,
					D3D11_INPUT_PER_VERTEX_DATA, 0 }, };
	UINT numElements = ARRAYSIZE( layout );

	// Create the input layout
	hr = pd3dDevice->CreateInputLayout( layout, numElements,
			pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(),
			&vertexLayout );
	pVSBlob->Release();
	if ( FAILED( hr ))
		return;

	// Set the input layout
	context->IASetInputLayout( vertexLayout );

	// Compile the pixel shader
	ID3DBlob* pPSBlob = NULL;
	hr = CompileShaderFromFile( L"Shader.fx", "PS", "ps_4_0", &pPSBlob );
	if ( FAILED( hr )) {
		MessageBox( NULL, L"Failed to compile FX file.", L"Error", MB_OK );
		return;
	}

	// Create the pixel shader
	hr = pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(),
			pPSBlob->GetBufferSize(), NULL, &pixelShader );
	pPSBlob->Release();
	if ( FAILED( hr ))
		return;

	// Create vertex buffer
	SimpleVertex vertices[] = { { D3DXVECTOR3( xpos, ypos, 0.5f ), color }, {
			D3DXVECTOR3( xpos + width, ypos, 0.5f ), color }, { D3DXVECTOR3(
			xpos, ypos - height, 0.5f ), color }, { D3DXVECTOR3( xpos + width,
			ypos - height, 0.5f ), color } };

	D3D11_BUFFER_DESC bd;
	ZeroMemory( &bd, sizeof(bd) );
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(SimpleVertex) * 4;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory( &InitData, sizeof(InitData) );
	InitData.pSysMem = vertices;
	hr = pd3dDevice->CreateBuffer( &bd, &InitData, &vertexBuffer );
	if ( FAILED( hr ))
		return;
}

void Rectangle::render( DXEngine* engine ) {
	ID3D11DeviceContext* context = engine->getContext();

	// Set vertex buffer
	UINT stride = sizeof(SimpleVertex);
	UINT offset = 0;
	context->IASetVertexBuffers( 0, 1, &vertexBuffer, &stride, &offset );

	// Set primitive topology
	context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );

	// Render a triangle
	context->VSSetShader( vertexShader, NULL, 0 );
	context->PSSetShader( pixelShader, NULL, 0 );
	context->Draw( 4, 0 );
}

Rectangle::~Rectangle() {
	if ( vertexLayout )
		vertexLayout->Release();
	if ( vertexShader )
		vertexShader->Release();
	if ( vertexBuffer )
		vertexBuffer->Release();
	if ( pixelShader )
		pixelShader->Release();
}

} /* namespace aole */
